#!/usr/bin/env python
#coding=utf8

#Testes de simulador

#import SimPy.SimulationTrace as simulation
import SimPy.Simulation as simulation
import random

#TODO: Ver se precisa de um semente melhor, de todo modo 12343 é um número primo
GENERATOR = random.Random(12343)

class Source(simulation.Process):
    ''' Classe que abstrai a chegada de requisições
    '''
    def __init__(self, mean=0.5):
        simulation.Process.__init__(self)
        self.mean = 1.0 / mean
        
    def connect(self, process):
        self.out = process

    def run(self):
        while True:
            yield simulation.hold, self, GENERATOR.expovariate(self.mean)
            yield simulation.request, self, self.out
    pass

class Server(simulation.Process):
    ''' Classe que simula o comportamento do servidor web que recebe as requisições de impressão.
        O tempo de preocessamento de uma requisiçã ode impressão é distribuido exponencialmente
    '''
    #TODO: O server tem de ter uma fila. SimJava tinha uma fila por default
    NEXT_ID = 0
    def __init__(self, mean=0.5):
        simulation.Process.__init__(self)
        self.ID = Server.NEXT_ID
        Server.NEXT_ID += 1
        self.mean = 1.0 / mean #inverso da media do tempo de processamento
                
    def run(self):
        while True:
            #TODO? Como faz para ver se chegou alguma requisição aqui? Tem de criar o método de 
            yield simulation.hold, self, GENERATOR.expovariate(self.mean)
    pass

class LAN(simulation.Process):
    ''' Classe que simula o comportamento de atraso gerado por uma rede local
    '''
    pass
    
class Printer(simulation.Process):
    ''' Classe que simula o comportamento de uma impressora
    '''
    #TODO: Construção com parãmetros de configuração para diferenciar as impressoras
    pass
    
def main():
    ''' Método que encapsula o comportamento executável do simulador
    '''
    #TODO: Mecanismo que extrai o esquema da rede de filas de um arquivo de configuração 
    #(configurações das entidades, quantidades e tipos de impressoras, etc.)
    simulation.initialize()
    src = Source()
    s = Server()
    src.connect(s)
    simulation.activate(s, s.run())
    maxsimtime = 1000
    simulation.simulate(until=maxsimtime)
    pass
    
if __name__ == '__main__':
    main()
